#ifndef Algebra_MpiCommunicator_h
#define Algebra_MpiCommunicator_h

#include "AlgebraModule.h"
// #include "MpiDataType.h"
#include "mpi.h"

SG_NAMESPACE_OPEN
namespace Algebra
{
    /**
     * @brief Manage the communication among a group of processes.
     *
     * A communicator contains a set of processes that can send messages among themselves and perform
     * collective operations. There can be many communicators within a single program, each of which
     * contains its own isolated communication space that acts independently of the other communicators.
     *
     * @see https://www.boost.org/doc/libs/1_85_0/doc/html/mpi/tutorial.html
     *
     * @author nene
     * @date December, 2024.
     */
    class ALGEBRA_EXPORT MpiCommunicator
    {
    public:
        MpiCommunicator();
        MpiCommunicator (const MPI_Comm& comm);
        ~MpiCommunicator ();

        /// Return the rank of the executing process in a communicator.
        int rank ();

        /// Return the number of processes in a communicator.
        int size ();

        /// Perform a blocking send.
        template <typename TDataType>
        void send (int dest, int tag, TDataType* buffer, int count);

        /// Blocking receive for a message.
        template <typename TDataType>
        void recv (int source, int tag, TDataType* buffer, int count);

        /// Broadcast a message from the current process.
        template <typename TDataType>
        void bcast (int root, TDataType* buffer, int count);

        // Block until all processes in the communicator have reached this routine.
        void barrier ();

    protected:
        MPI_Comm mComm;  //< the underlying MPI communicator.
    };
}  // namespace Algebra

SG_NAMESPACE_CLOSE

#endif  //  Algebra_MpiCommunicator_h